﻿
#if NET_4
using System.Linq;
#endif
 
using System;
using TSharp.Core.Exceptions;

namespace TSharp.Core
{
    /// <summary>
    /// 数组扩展类
    /// </summary>
    public static class Extension
    {
        /// <summary>
        /// 将当前数据组转为16进制
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToHexString(this byte[] bytes)
        {
            if (bytes == null) return "";
            return string.Join("", Array.ConvertAll(bytes, x => x.ToString("X2")));
        }

        /// <summary>
        /// 将16进制字符串转为字节数组
        /// </summary>
        /// <param name="hexString">The hex string.</param>
        /// <returns></returns>
        public static byte[] ToByteArray(this string hexString)
        {
            if (string.IsNullOrEmpty(hexString)) return null;
            return Array.ConvertAll(hexString.ToCharArray(), x => (byte)x);
        }

        /// <summary>
        /// 在当前byte数组后追加新的数组
        /// </summary>
        /// <param name="curr"></param>
        /// <param name="after"></param>
        /// <returns></returns>
        public static byte[] Append(this byte[] curr, byte[] after)
        {
            if (curr != null && after != null)
            {
                //byte[] s;
                //s = new byte[curr.LongLength + after.LongLength];
                //Array.Copy(curr, 0, s, 0, curr.LongLength);
                //Array.Copy(after, 0, s, curr.LongLength, after.LongLength);
                //return s;

                byte[] s = (byte[])curr.Clone();
                Array.Resize<byte>(ref s, curr.Length + after.Length);
                Array.Copy(after, 0, s, curr.Length, after.Length);
                return s;
            }
            if (curr == null)
            {
                return after;
            }
            if (after == null)
                return curr;
            return null;
        }

        /// <summary>
        /// 从当前数组截取并组成新数组
        /// </summary>
        /// <param name="curr"></param>
        /// <param name="index"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static byte[] SubByte(this byte[] curr, long index, long length)
        {
            if (index < 0)
                throw new ArgumentException("不能小于0。", "index");
            if (curr == null)
                return null;
            if ((curr.LongLength - index) < length)
                throw new ArgumentException("参数不正确。");
            var n = new byte[length];
            Array.Copy(curr, index, n, 0, length);
            return n;
        }

        /// <summary>
        /// 断言 为null
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="message"></param>
        internal static void IsNull<T>(this T obj, string message) where T : class
        {
            Is(obj, x => x == null, message);
        }

        /// <summary>
        /// 断言
        /// </summary>
        /// <typeparam name="T">断言参数类型</typeparam>
        /// <param name="obj">断言类型</param>
        /// <param name="func">The func.</param>
        /// <param name="message">断言提示信息</param>
        internal static void Is<T>(this T obj, Func<T, bool> func, string message)
        {
            if (func(obj))
                throw new CoreException(message);
        }
        /// <summary>
        /// 将指定字符串中的一个或多个格式项替换为指定对象的字符串表示形式。
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="args">The args.</param>
        /// <returns></returns>
        public static string FormatPad(this string template, params object[] args)
        {
            return string.Format(template, args);
        }
        /// <summary>
        /// Formats the specified template.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="arg1">The arg1.</param>
        /// <returns></returns>
        public static string Format(this string template, object arg1)
        {
            return string.Format(template, arg1);
        }
        /// <summary>
        /// Formats the pad.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="arg1">The arg1.</param>
        /// <param name="arg2">The arg2.</param>
        /// <returns></returns>
        public static string FormatPad(this string template, object arg1, object arg2)
        {
            return string.Format(template, arg1, arg2);
        }
        /// <summary>
        /// Formats the pad.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="arg1">The arg1.</param>
        /// <param name="arg2">The arg2.</param>
        /// <param name="arg3">The arg3.</param>
        /// <returns></returns>
        public static string FormatPad(this string template, object arg1, object arg2, object arg3)
        {
            return string.Format(template, arg1, arg2, arg3);
        }
    }
}